package mrusanov.player.psychology

import util.Random
import mrusanov.player.Player
import mrusanov.team.Team

object PlayerPsychology {
  def createRandomPsychology(player:Player) = new PlayerPsychology(player, _0_100, _0_100, _0_100, _0_100,_0_100)

  private def _0_100 = Random.nextInt(101)

  private val averageConflictChance = 0.1 // this value may be changed
  private val averageConflictDifference = 0.125
  private val conflictPower = scala.math.log(averageConflictChance) / scala.math.log(averageConflictDifference)

  private val averageFriendshipChance = 0.05 // this value may be changed
  private val averageFriendshipDifference = 0.125
  private val friendshipPower = scala.math.log(averageFriendshipChance) / scala.math.log(averageFriendshipDifference)

  val SHAPE_BONUS_FOR_FRIEND = 5
  val SHAPE_PENALTY_FOR_FOE = 10

  def conflictCorrection(x:Double):Double = scala.math.pow(x / 100d, conflictPower) * 100
  def friendshipCorrection(x:Double):Double = scala.math.pow(x / 100d, friendshipPower) * 100
}

class PlayerPsychology private[psychology] (val player:Player, val ambition:Int, val discipline:Int,
      val worldView:Int, val conflict:Int, val talkative:Int) {

  var friends:Set[Player] = Set()
  var enemies:Set[Player] = Set()

  var motivation = NormalMotivation

  private var _relationshipShapeBonus = 0

  def relationshipShapeBonus = _relationshipShapeBonus

  def updatePsychologicalStateBeforeGame(roster:List[Player]) {
    // TODO add motivation changes, counters

    _relationshipShapeBonus = calculateRelationshipShapeBonus(roster.toSet) + motivation.shapeBonus
  }

  def chanceOfConflict(that:PlayerPsychology):Int = {
    val viewDifference = scala.math.abs(this.worldView - that.worldView) // avg = 50
    val totalConflict = scala.math.sqrt(this.conflict * that.conflict)  // avg = 50
    val totalTalkativeness = (this.talkative + that.talkative) / 20000d  // 100 / 20 000
    PlayerPsychology.conflictCorrection(totalConflict * viewDifference * totalTalkativeness).round.toInt
  }

  def chanceOfFriendship(that:PlayerPsychology):Int = {
    val viewCommonPart = 100 - scala.math.abs(this.worldView - that.worldView) // avg = 50
    val antiConflictAvg = 100 - (this.conflict + that.conflict) / 2d // avg = 50
    val talkativenessAvg = (this.talkative + that.talkative) / 20000d // avg = 50 / 20000
    PlayerPsychology.friendshipCorrection(viewCommonPart * antiConflictAvg * talkativenessAvg).round.toInt
  }

  private def calculateRelationshipShapeBonus(players:Set[Player]):Int = {
    val friendsCount = friends.intersect(players).size
    val enemiesCount = enemies.intersect(players).size

    PlayerPsychology.SHAPE_BONUS_FOR_FRIEND * friendsCount + PlayerPsychology.SHAPE_PENALTY_FOR_FOE * enemiesCount
  }
}
